/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package session;

import event.JobAlarmEvent;
import event.JobConfirmEvent;
import event.JobSendableEvent;
import event.JobStatusEvent;
import net.sf.appia.core.AppiaEventException;
import net.sf.appia.core.Direction;
import net.sf.appia.core.Event;
import net.sf.appia.core.Layer;
import net.sf.appia.core.Session;
import net.sf.appia.core.events.channel.ChannelInit;
import net.sf.appia.protocols.common.RegisterSocketEvent;
import util.Constants;
import util.Debug;
import util.Status;

/**
 *
 * @author Welington
 */
public class TransformationSession extends Session {
    private int bound;
    private Class current = TransformationSession.class;
    private Debug debug = Debug.getInstance();

    /** Creates a new instance of BoundedPrintSession */
    public TransformationSession(Layer layer) {
        super(layer);
    }

    @Override
    public void handle(Event event) {
        if (event instanceof ChannelInit) {
            handleChannelInit((ChannelInit) event);
        } else if (event instanceof RegisterSocketEvent) {
            handleRegisterSocket((RegisterSocketEvent) event);
        } else if (event instanceof JobSendableEvent) {
            if (event.getDir() == Direction.DOWN) {
                handleSendableEvent((JobSendableEvent) event);
            } else {
                handleDeliverySendableEvent((JobSendableEvent) event);
            }
        } else if (event instanceof JobConfirmEvent) {
            handleJobConfirm((JobConfirmEvent) event);
        }
    }

    private void handleChannelInit(ChannelInit init) {
        try {
            bound = 5;

            init.go();
        } catch (AppiaEventException e) {
            debug.print(Debug.ERROR, current, e.getLocalizedMessage());
        }
    }

    private void handleRegisterSocket(RegisterSocketEvent event) {
        try {
            event.go();
        } catch (AppiaEventException ex) {
            debug.print(Debug.ERROR, current, ex.getLocalizedMessage());
        }
    }
    
    private void handleSendableEvent(JobSendableEvent event) {
        if (bound > 0) {
            bound--;
            debug.print(Debug.INFO, current, "Transforming request [" + event.getId() + "]");
            
            String  content = Constants.extractContent(event.getMessage());
            event.setMessage(Constants.buildMessage(content.toUpperCase()));
            
            try {
                event.go();
            } catch (AppiaEventException e) {
                debug.print(Debug.ERROR, current, e.getLocalizedMessage());
            }
            if (bound == 0) {
                JobAlarmEvent alarm = new JobAlarmEvent();
                alarm.setChannel(event.getChannel());
                alarm.setDir(Direction.UP);
                alarm.setSourceSession(this);
                try {
                    alarm.init();
                    alarm.go();
                } catch (AppiaEventException e) {
                    debug.print(Debug.ERROR, current, e.getLocalizedMessage());
                }
            }
        } else {
            JobStatusEvent status = new JobStatusEvent();
            status.setChannel(event.getChannel());
            status.setDir(Direction.UP);
            status.setSourceSession(this);
            status.setId(event.getId());
            status.setStatus(new Status(Status.StatusType.NOK));
            
            try {
                status.init();
                status.go();
            } catch (AppiaEventException e) {
                debug.print(Debug.ERROR, current, e.getLocalizedMessage());
            }
        }
    }

    private void handleDeliverySendableEvent(JobSendableEvent event) {
        debug.print(Debug.LOG, current, "Message received from Job Layer. Sending to upper layer...");

        try {
            event.go();
        } catch (AppiaEventException ex) {
            debug.print(Debug.ERROR, current, ex.getLocalizedMessage());
        }
    }
    
    private void handleJobConfirm(JobConfirmEvent conf) {
        JobStatusEvent status = new JobStatusEvent();
        status.setId(conf.getId());
        status.setStatus(new Status(Status.StatusType.OK));

        debug.print(Debug.INFO, current, "Received confirmation of request [" + conf.getId() + "]");
        
        try {
            bound++;
            status.setChannel(conf.getChannel());
            status.setDir(Direction.UP);
            status.setSourceSession(this);
            status.init();
            status.go();
        } catch (AppiaEventException e) {
            debug.print(Debug.ERROR, current, e.getLocalizedMessage());
        }

    }
}
